import {RequestMethod} from "../lib/defines";
import {MemberBase, RoomBase} from "../utils/types";
import {ChatModeEnums} from "../utils/enums";


export type OfferQuery = {
  // 用户 sdpOffer
  offer: string;

  // 所属用户
  member: MemberBase;

  // 所属房间
  room: RoomBase;
}

export default function offer (app) {
  const { socket, rooms } = app.locals;
  const { userId } = socket.handshake.query;

  /**
   * origin: 流的来源
   * target: 流向的目标
   */
  socket.on(RequestMethod.offer, async function(data: OfferQuery, cb) {
    const { clientUtils } = app.locals;
    const { offer, member, room } = data;
    if (!room) {
      return cb && cb({status: 'error', message: 'room not find!'})
    }
    const __room = rooms[room.classId]

    if (!__room) {
      return cb && cb({status: 'error', message: 'room not find!'})
    }

    const __member = __room.members[member.userId];

    if (!__member) {
      return cb && cb({status: 'error', message: 'member not find!'})
    }


    // console.log('==============> ', __member)
    const endpoint = __member.getEndpoint(member.userId);
    let candidatesQueue = __member.candidatesQueue[userId] || (__member.candidatesQueue[userId] = [])

    socket.join(room.classId);



    // 加入 临时房间
    // __room.setMember(__member);
    if (member.userId === userId) {
      if (__room.chatMode === ChatModeEnums.BROADCAST && __member.player) {
        await clientUtils.connect(__member.player, endpoint);
        __member.player.play(function (error) {
          if (error) return ;
        })
      }

      /**
       * 自己的 offer
       */
      clientUtils.processOffer(endpoint, offer, (sdpAnswer) => {
        socket.emit('answer', { sdpAnswer, member });

        console.log('------- joined --------')
        // 通知当前房间的其他人，但是自己并不收到消息
        socket.broadcast
          .to(room.classId)
          .emit('joined', { member, room });
      });
    } else {
      /**
       * 其他人的 offer
       */
      clientUtils.createEndpoint(__member.pipeline, (targetEndpoint) => {
        while(candidatesQueue.length) {
          const candidate = candidatesQueue.shift();
          targetEndpoint.addIceCandidate(candidate);
        }

        clientUtils.onIceCandidate(targetEndpoint, (iceCandidate) => {
          socket.emit('iceCandidate', { iceCandidate, member });
        });

        clientUtils.processOffer(targetEndpoint, offer, async (sdpAnswer) => {
          if (__room.chatMode === ChatModeEnums.BROADCAST && __member.player) {
            await clientUtils.connect(__member.player, targetEndpoint);
          } else {
            clientUtils.connect(endpoint, targetEndpoint);
          }

          __member.setEndpoint(userId, targetEndpoint);
          socket.emit('answer', { sdpAnswer, member });
        });
      });
    }

    // 回调
    if (cb) {
      cb({status: 'ok', resolve: 'offer' })
    }
  });
}
